﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Globalization;
using System.IO;
using WIKID.Model;
using WIKID.Accessor;
using WIKID.Common;

namespace WIKID.Controller
{
    class ParentController
    {
        private Utils utils = new Utils();
        
        /// <summary>
        /// Method to check username/password of parent
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public Constants.LOGIN_RESULT CheckPass(string username, string password)
        {
            string[] config = File.ReadAllLines(Constants.CONFIG_FILE);

            if (!utils.VerifyMd5Hash(username, config[0]))
                return Constants.LOGIN_RESULT.InvalidID;
            else
            {
                if (!utils.VerifyMd5Hash(password, config[1]))
                    return Constants.LOGIN_RESULT.InvalidPassword;
                else
                    return Constants.LOGIN_RESULT.Success;
            }
            
        }

        /// <summary>
        /// Method to change username/password of parent
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        public void ChangePass(string username, string password)
        {
            string[] usernamePassHashed = {utils.GetMd5Hash(username),utils.GetMd5Hash(password)};
            File.WriteAllLines(Constants.CONFIG_FILE, usernamePassHashed);
        }

        /// <summary>
        /// Listing Accounts' Id & Name
        /// </summary>
        /// <returns></returns>
        public Dictionary<int,string> ListingAccounts()
        {
            Dictionary<int, string> dicAccounts = new Dictionary<int, string>();
            List<string> lsAccounts = new List<string>();
            List<string> lsAccName = new List<string>();
            int accId;
            string accName;
            int separateCharIndex;
            lsAccounts = utils.ListingXMLFiles(Constants.ACCOUNTS_FOLDER);
            foreach (string strAccount in lsAccounts)
            {
                separateCharIndex = strAccount.IndexOf(Constants.SEPARATE_CHAR);
                accId = Convert.ToInt32(strAccount.Substring(0, separateCharIndex));
                accName = strAccount.Substring(separateCharIndex + 1);
                dicAccounts.Add(accId, accName);
            }
            return dicAccounts;
        }

        /// <summary>
        /// Listing all knowledge sources/subjects
        /// </summary>
        /// <returns></returns>
        public Dictionary<int, string> ListingSubjects()
        {
            Dictionary<int, string> dicSubjects = new Dictionary<int, string>();
            List<string> lsSubjects = new List<string>();
            List<string> lsSubjectName = new List<string>();
            int subjectId;
            string subjectName;
            int separateCharIndex;
            lsSubjects = utils.ListingSubFolders(Constants.SUBJECTS_FOLDER);
            foreach (string strSubject in lsSubjects)
            {
                if (char.IsDigit(strSubject, 0) && strSubject.Contains(Constants.SEPARATE_CHAR))
                {
                    separateCharIndex = strSubject.IndexOf(Constants.SEPARATE_CHAR);
                    subjectId = Convert.ToInt32(strSubject.Substring(0, separateCharIndex));
                    subjectName = strSubject.Substring(separateCharIndex + 1);
                    dicSubjects.Add(subjectId, subjectName);
                }
            }
            return dicSubjects;
        }

        /// <summary>
        /// Listing all lectures in the knowledge source/subject
        /// </summary>
        /// <returns></returns>
        public Dictionary<int, string> ListingLectures(KeyValuePair<int,string> subject)
        {
            Dictionary<int, string> dicLectures = new Dictionary<int, string>();
            List<string> lsLectures = new List<string>();
            List<string> lsLectureName = new List<string>();
            int lectureId;
            string lectureName;
            string subjectFolder = subject.Key.ToString() + Constants.SEPARATE_CHAR + subject.Value;
            int separateCharIndex;
            lsLectures = utils.ListingSubFolders(Constants.SUBJECTS_FOLDER + @"\" + subjectFolder);
            foreach (string strLecture in lsLectures)
            {
                if (Char.IsDigit(strLecture, 0) && strLecture.Contains(Constants.SEPARATE_CHAR))
                {
                    separateCharIndex = strLecture.IndexOf(Constants.SEPARATE_CHAR);
                    lectureId = Convert.ToInt32(strLecture.Substring(0, separateCharIndex));
                    lectureName = strLecture.Substring(separateCharIndex + 1);
                    dicLectures.Add(lectureId, lectureName);
                }
            }
            return dicLectures;
        }
        

        /// <summary>
        /// Method to update Schedule for a account
        /// </summary>
        /// <param name="accountModel"></param>
        /// <param name="scheduleModel"></param>
        /// <returns></returns>
        public bool UpdateSchedule(AccountModel accountModel, ScheduleModel scheduleModel)
        {
            try
            {
                XMLWriter xmlWriter = new XMLWriter();
                //Remove old schedule of a lecture if exist
                foreach(ScheduleModel tempSchedule in accountModel.Schedules)
                {
                    if (tempSchedule.LectureId.Equals(scheduleModel.LectureId))
                    {
                        accountModel.Schedules.Remove(tempSchedule);
                        break;
                    }
                }
                accountModel.Schedules.Add(scheduleModel);
                xmlWriter.updateXML(accountModel);

                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accName"></param>
        /// <returns></returns>
        public AccountModel GetAccountModel(string accName)
        {
            XMLReader xmlReader = new XMLReader();
            AccountModel accountModel = new AccountModel();
            accountModel = xmlReader.getAccountByXmlFileName(accName);
            return accountModel;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accountModel"></param>
        /// <returns></returns>
        public List<ScoreModel> GetWeeklyScores(AccountModel accountModel)
        {
            List<ScoreModel> lsScoreModel = new List<ScoreModel>();
            foreach(ScoreModel scoreModel in accountModel.Scores)
            {
                if (GetWeekOfYear(scoreModel.Date) == GetWeekOfYear(DateTime.Now) &&
                    scoreModel.Date.Year == DateTime.Now.Year)
                {
                    lsScoreModel.Add(scoreModel);
                }
            }

            return lsScoreModel;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accountModel"></param>
        /// <returns></returns>
        public List<ScoreModel> GetMonthlyScores(AccountModel accountModel)
        {
            List<ScoreModel> lsScoreModel = new List<ScoreModel>();
            foreach (ScoreModel scoreModel in accountModel.Scores)
            {
                if (scoreModel.Date.Month == DateTime.Now.Month &&
                    scoreModel.Date.Year == DateTime.Now.Year)
                {
                    lsScoreModel.Add(scoreModel);
                }
            }

            return lsScoreModel;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        private int GetWeekOfYear(DateTime date)
        {
            return CultureInfo.CurrentUICulture.Calendar.GetWeekOfYear(date,
                CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
        }
    }
}
